package com.base.myproject.client.tools;

import java.util.Date;

/**
 * 
 * @author zgw
 *2009-12-8 上午11:56:04
 * javazgw@gmail.com
 */
public class CalendarUtils {
	private static final long MS_PER_SEC = 1000;
    private static final long MS_PER_MIN = MS_PER_SEC * 60;
    private static final long MS_PER_HOUR = MS_PER_MIN * 60;
    private static final long MS_PER_DAY = MS_PER_HOUR * 24;
    
    private CalendarUtils()
    {
    }
    
    public static Date truncateToTime(Date date)
    {
        long time = date.getTime();
        return new Date(time - truncateToDay(date).getTime());
    }
    
    public static Date truncateToDay(Date date)
    {
        return new Date(date.getYear(), date.getMonth(), date.getDate());
    }
    
    public static Date truncateToMonth(Date date)
    {
        return addDays(truncateToDay(date), 1 - date.getDate());
    }
    
    public static Date truncateToYear(Date date)
    {
        date = truncateToMonth(date);
        date.setMonth(0);
        return date;
    }
    
    public static Date addDays(Date date, int days)
    {
        Date newDate = new Date(date.getTime());
        newDate.setDate(date.getDate() + days);
        return newDate;
    }
    
    public static Date addMonths(Date date, int months)
    {
        for (; months < 0; months++)
        {
            Date roundedPriorMonth = addDays(truncateToMonth(date), -1);
            date = addDays(date, -getDaysInMonth(roundedPriorMonth)); 
        }
        for (; months > 0; months--)
        {
            date = addDays(date, getDaysInMonth(date));
        }
        return date;
    }
    
    public static int getDaysInMonth(Date date)
    {
        return getDaysInMonth(date.getYear() + 1900, date.getMonth());
    }
    
    public static int getDaysInMonth(int year, int month)
    {
        switch (month)
        {
            case 1:
                return (((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0) ? 29 : 28;
    
            case 3:
            case 5:
            case 8:
            case 10:
                return 30;
                
            default:
                return 31;
        }
    }

    /**
     * Determines the number of days between two dates, always rounding up so a difference of 1 day 1 second
     * yield a return value of 2.
     */
    public static int dayDiff(Date endDate, Date startDate)
    {
         return (int)Math.ceil(((double)endDate.getTime() - startDate.getTime()) / MS_PER_DAY);
    }
}
